#include "stdafx.h"
#include "MemoryAlloc.h"
#include <irrlicht.h>
/*
void* operator new (unsigned int aiSize) 
{
	if (!aiSize) 
	{
//		MC_knlPrintk("MALLOC(0) attempted\n");
		aiSize = 1;
	}
	// we need to store the id necessary to free the allocated memory
	// so alloc 4 bytes more, and store it at start, then return the pointer + 4 bytes
	signed long memID;
	aiSize = (aiSize + 3) &~ 3;
	memID = MC_knlAlloc( aiSize + 4 );
	if (memID == 0)
		return NULL;
	signed long * ptr = (signed long *)MC_GETDPTR(memID);
	*ptr = memID;
	memset(ptr + 1,0 ,aiSize);

//	MC_knlPrintk( (signed char *)"memID = %d, ptr = %d\n", *ptr, (ptr + 1) );

	return (ptr + 1);


}

void operator delete (void* apLocation) 
{
	if (apLocation)
	{
		signed long memID = *((signed long *)apLocation - 1);
		MC_knlFree(memID);
	}
	//FREE( apLocation );
}

*/

#ifdef _WIPIVERSION
#include "HQM3DPredefine.h"

void* malloc(unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber)
{
	if (!blocksize) 
	{
		return NULL;
	}
	// we need to store the id necessary to free the allocated memory
	// so alloc 4 bytes more, and store it at start, then return the pointer + 4 bytes
	signed long memID;
	blocksize = (blocksize + 3) &~ 3;
	memID = MC_knlAlloc( blocksize + 4 );
	if (memID == 0)
		return NULL;
	signed long * ptr = (signed long *)MC_GETDPTR(memID);
	*ptr = memID;
	memset(ptr + 1,0 ,blocksize);

	return (ptr + 1);
}

void free(void* block)
{
	if(block)
	{
		signed long memID = *((signed long *)block - 1);
		MC_knlFree(memID);
	}
}

void* operator new(unsigned int blocksize)
{
	return malloc(blocksize,"",0);
}
void* operator new[](unsigned int blocksize)
{
	return malloc(blocksize,"",0);
}

void  operator delete( void* block )
{
	free(block);
}

void  operator delete[]( void* block )
{
	free(block);
}

void* operator new(unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber)
{
	return malloc(blocksize,in_pszFileName,in_nLineNumber);
}
void* operator new[](unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber)
{
	return malloc(blocksize,in_pszFileName,in_nLineNumber);
}

#elif defined __SYMBIAN32__

#include "e32std.h"
#include "string.h"

void* malloc(unsigned int blocksize,const char * in_pszFileName, const int in_nLineNumber)
{
	void* ptr = 0;
	int nError = KErrNone;
	TRAP(nError,ptr = User::AllocL(blocksize));
	if(nError != KErrNone)
	{
//		User::Leave(KErrNoMemory);
		User::Exit(KErrNoMemory);
	}
    memset(ptr,0,blocksize);
	return ptr;
}

void free(void* block)
{
	if(block)
	{
		User::Free(block);
	}
}

void* operator new(unsigned int in_nSize,int xxx) 
{
	return malloc(in_nSize,"",0);
}

void* operator new[](unsigned int in_nSize,int xxx) 
{
	return malloc(in_nSize,"",0);
}


void* operator new(unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber)
{
	return malloc(blocksize,in_pszFileName,in_nLineNumber);
}
void* operator new[](unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber)
{
	return malloc(blocksize,in_pszFileName,in_nLineNumber);
}

#elif defined _BREWVERSION

#else
#include <stdlib.h>

#ifndef _USEMEMMANAGER
/*
	void* operator new(unsigned int in_nSize,int xxx) 
	{
		void* ptr = 0;
		ptr = malloc(in_nSize);
		memset(ptr,0,in_nSize);
		return ptr;
	}

	void* operator new[](unsigned int in_nSize,int xxx) 
	{
		void* ptr = 0;
		ptr = malloc(in_nSize);
		memset(ptr,0,in_nSize);
		return ptr;
	}
*/
	void* malloc(int blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	{
		if(blocksize <= 0)
			return NULL;
		void * ptr = 0;
		ptr = malloc(blocksize);
		memset(ptr,0,blocksize);
		//
		return ptr;
	}

	void free(void* block,int xxx,int xxx2)
	{
		if(block == NULL)
			return;
		//
		free(block);
		//
	}
#ifndef IPHONEOS
	//void* operator new(unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	//{
	//	return malloc(blocksize,in_pszFileName,in_nLineNumber,xxx,xxx2);
	//}

	//void* operator new[](unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	//{
	//	return malloc(blocksize,in_pszFileName,in_nLineNumber,xxx,xxx2);
	//}
#else
	void* operator new(size_t blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	{
		return malloc(blocksize,in_pszFileName,in_nLineNumber,xxx,xxx2);
	}

	void* operator new[](size_t blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	{
		return malloc(blocksize,in_pszFileName,in_nLineNumber,xxx,xxx2);
	}
#endif
/*
	void* operator new(unsigned int blocksize,enum irr::MemHint,int nXX,const char* in_pszFileName, const int in_nLineNumber)
	{
		return malloc(blocksize,in_pszFileName,in_nLineNumber,0,1);
	}
*/

	//void operator delete(void * pBuffer)
	//{
	//	free(pBuffer,1,2);
	//}

	//void operator delete[](void * pBuffer)
	//{
	//	free(pBuffer,1,2);
	//}

//	void* IrrAlloc(size_t size, irr::MemHint hint) 
//	{
//		return malloc(size);
////		return malloc(size,filename,line,0,0);
//	}
//	void* IrrAlloc(size_t size, irr::MemHint hint, int block, const char* filename, int line)
//	{
////		return malloc(size);
//		return malloc(size,filename,line,0,0);
//	}

	void IrrFree(void* p)
	{
		free(p);
	}


#else
	#include "afxtempl.h"
	struct _MemoryStatus
	{
		char 				szFileName[128];
		int					nLineNumber;
		//
		void *				pBuffer;
		int					nSize;
	};
	CList<_MemoryStatus,_MemoryStatus>	g_MemoryStatusList;
	BOOL								g_bInMemStatusCheck = FALSE;

	void MemStack_Begin_SnapShot()
	{
		g_MemoryStatusList.RemoveAll();
		g_bInMemStatusCheck = TRUE;
	}

	void MemStack_End_SnapShot()
	{
		g_bInMemStatusCheck = FALSE;
		//
		int nLeakCount = g_MemoryStatusList.GetCount();
		POSITION pos;
		_MemoryStatus Status;
		int i;
		for(i=0;i<nLeakCount;i++)
		{
			pos = g_MemoryStatusList.FindIndex(i);
			if(pos)
			{
				Status = g_MemoryStatusList.GetAt(pos);
				TRACE("Detect Mem Leak, File:%s,Line:%d,Size:%d\n",Status.szFileName,Status.nLineNumber,Status.nSize);
				free(Status.pBuffer);
			}
		}
		g_MemoryStatusList.RemoveAll();
	}

	void* malloc(int blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	{
		if(blocksize <= 0)
			return NULL;
		void * ptr = 0;
		ptr = malloc(blocksize);
		memset(ptr,0,blocksize);
		//
		if(g_bInMemStatusCheck)
		{
			_MemoryStatus Status;
			strcpy(Status.szFileName,in_pszFileName);
			Status.nLineNumber = in_nLineNumber;
			Status.nSize = blocksize;
			Status.pBuffer = ptr;
			g_MemoryStatusList.AddTail(Status);
		}
		//
		return ptr;
	}

	POSITION FindMemStatusByBuffer(void * pBuffer)
	{
/*		int i,count = g_MemoryStatusList.GetCount();
		POSITION pos;
		_MemoryStatus Status;
		for(i=0;i<count;i++)
		{
			pos = g_MemoryStatusList.FindIndex(i);
			if(pos)
			{
				Status = g_MemoryStatusList.GetAt(pos);
				if(Status.pBuffer == pBuffer)
					return pos;
			}
		}
*/
		POSITION pos,OldPos;
		_MemoryStatus Status;
		pos = g_MemoryStatusList.GetHeadPosition();
		while(pos)
		{
			OldPos = pos;
			Status = g_MemoryStatusList.GetNext(pos);
			if(Status.pBuffer == pBuffer)
				return OldPos;
		}
		return NULL;
	}

	void free(void* block,int xxx,int xxx2)
	{
		if(block == NULL)
			return;
		//
		free(block);
		//
		if(g_bInMemStatusCheck)
		{
			POSITION pos = FindMemStatusByBuffer(block);
			if(!pos)
			{
//				TRACE("Can't Find Block :%d\n",(int)block);
			}
			else
			{
				g_MemoryStatusList.RemoveAt(pos);
			}
		}
	}

	void* operator new(unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	{
		return malloc(blocksize,in_pszFileName,in_nLineNumber,xxx,xxx2);
	}

	void* operator new[](unsigned int blocksize, const char* in_pszFileName, const int in_nLineNumber,int xxx,int xxx2)
	{
		return malloc(blocksize,in_pszFileName,in_nLineNumber,xxx,xxx2);
	}

	void operator delete(void * pBuffer)
	{
		free(pBuffer,1,2);
	}

	void operator delete[](void * pBuffer)
	{
		free(pBuffer,1,2);
	}

	void* IrrAlloc(size_t size, irr::MemHint hint) 
	{
		return malloc(size,"None",0,1,2);
	}
	void* IrrAlloc(size_t size, irr::MemHint hint, int block, const char* filename, int line)
	{
//		return IrrAlloc(size, hint);
		return malloc(size,filename,line,1,2);
	}

	void IrrFree(void* p)
	{
		free(p,1,2);
	}

#endif

#endif



